package com.ruoyi.common.utils.detection;

import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONArray;

/**
 * 检测服务工具类
 * 封装图片检测相关的通用功能
 * 
 * @author ruoyi
 */
public class DetectionService
{
    private static final Logger log = LoggerFactory.getLogger(DetectionService.class);
    
    /**
     * 调用检测API进行图片检测
     * 
     * @param apiUrl 检测API地址
     * @param imagePath 图片文件路径
     * @return 检测结果JSON字符串
     */
    public static String detectImage(String apiUrl, String imagePath)
    {
        try
        {
            if (StringUtils.isEmpty(apiUrl))
            {
                log.error("检测API地址为空");
                return null;
            }
            
            if (StringUtils.isEmpty(imagePath))
            {
                log.error("图片文件路径为空");
                return null;
            }
            
            // 确保API URL格式正确
            if (!apiUrl.startsWith("http://") && !apiUrl.startsWith("https://"))
            {
                apiUrl = "http://" + apiUrl;
            }
            
            log.info("调用检测API，URL: {}, 图片文件: {}", apiUrl, imagePath);
            
            // 发送HTTP POST请求（带文件上传）
            String response = HttpUtils.sendPostWithFile(apiUrl, imagePath, "images");
            
            if (StringUtils.isNotEmpty(response))
            {
                log.info("检测API调用成功，响应长度: {}", response.length());
                return response;
            }
            else
            {
                log.warn("检测API调用完成，但响应内容为空");
                return null;
            }
        }
        catch (Exception e)
        {
            log.error("调用检测API时发生异常，API URL: {}, 图片路径: {}, 异常信息: {}", apiUrl, imagePath, e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 保存上传的图片到本地
     * 
     * @param imageBytes 图片字节数组
     * @param originalFileName 原始文件名
     * @param prefix 文件名前缀
     * @return 本地文件路径
     */
    public static String saveUploadedImage(byte[] imageBytes, String originalFileName, String prefix)
    {
        try
        {
            // 获取文件扩展名
            String fileExtension = "";
            if (originalFileName != null && originalFileName.contains("."))
            {
                fileExtension = originalFileName.substring(originalFileName.lastIndexOf('.'));
            }
            
            // 生成唯一文件名
            String fileName = prefix + "_" + System.currentTimeMillis() + fileExtension;
            
            // 创建保存目录
            String uploadDir = RuoYiConfig.getProfile() + "/manual/";
            File directory = new File(uploadDir);
            if (!directory.exists())
            {
                directory.mkdirs();
            }
            
            // 保存文件
            String filePath = uploadDir + fileName;
            File file = new File(filePath);
            
            try (FileOutputStream fos = new FileOutputStream(file))
            {
                fos.write(imageBytes);
                fos.flush();
            }
            
            log.info("图片保存成功: {}", filePath);
            // 返回相对路径而不是绝对路径
            return "/manual/" + fileName;
        }
        catch (Exception e)
        {
            log.error("保存上传图片失败: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 解析检测结果
     * 
     * @param response 检测API响应
     * @return 解析后的检测结果
     */
    public static DetectionResult parseDetectionResponse(String response)
    {
        DetectionResult result = new DetectionResult();
        
        try
        {
            if (StringUtils.isEmpty(response))
            {
                result.setSuccess(false);
                return result;
            }
            
            log.debug("解析检测结果，响应长度: {}", response.length());
            
            // 解析JSON响应
            JSONObject jsonResponse = JSON.parseObject(response);
            JSONObject dataNode = jsonResponse.getJSONObject("data");
            
            if (dataNode != null && dataNode.containsKey("results"))
            {
                JSONArray resultsArray = dataNode.getJSONArray("results");
                
                if (resultsArray != null && resultsArray.size() > 0)
                {
                    // 获取第一个检测结果
                    JSONObject firstResult = resultsArray.getJSONObject(0);
                    
                    if (firstResult.getBooleanValue("success"))
                    {
                        result.setSuccess(true);
                        result.setRawResponse(response);
                        
                        // 处理检测结果
                        JSONArray detectionsArray = firstResult.getJSONArray("detections");
                        if (detectionsArray != null && detectionsArray.size() > 0)
                        {
                            // 获取第一个检测对象的信息
                            JSONObject firstDetection = detectionsArray.getJSONObject(0);
                            
                            // 设置置信度
                            if (firstDetection.containsKey("confidence"))
                            {
                                BigDecimal confidence = new BigDecimal(firstDetection.getDoubleValue("confidence"));
                                result.setConfidence(confidence);
                                
                                // 设置默认置信度阈值
                                BigDecimal threshold = new BigDecimal("0.5");
                                result.setConfThreshold(threshold);
                                
                                // 判断是否预警（置信度大于阈值）
                                if (confidence.compareTo(threshold) > 0)
                                {
                                    result.setDanger(1); // 预警
                                }
                                else
                                {
                                    result.setDanger(0); // 不预警
                                }
                            }
                            
                            // 检查严重程度
                            if (firstDetection.containsKey("severity"))
                            {
                                String severity = firstDetection.getString("severity");
                                if ("high".equals(severity))
                                {
                                    result.setDanger(1); // 高严重程度直接预警
                                }
                            }
                        }
                        else
                        {
                            // 没有检测到目标
                            result.setDanger(0);
                            result.setConfidence(BigDecimal.ZERO);
                            result.setConfThreshold(new BigDecimal("0.5"));
                        }
                    }
                    else
                    {
                        result.setSuccess(false);
                    }
                }
                else
                {
                    result.setSuccess(false);
                }
            }
            else
            {
                result.setSuccess(false);
            }
        }
        catch (Exception e)
        {
            log.error("解析检测结果时发生异常: {}", e.getMessage(), e);
            result.setSuccess(false);
        }
        
        return result;
    }
    
    /**
     * 从文件名中获取文件扩展名
     * 
     * @param fileName 文件名
     * @return 文件扩展名
     */
    private static String getFileExtension(String fileName)
    {
        try
        {
            if (StringUtils.isEmpty(fileName))
            {
                return ".jpg";
            }
            
            int lastDotIndex = fileName.lastIndexOf('.');
            if (lastDotIndex > 0 && lastDotIndex < fileName.length() - 1)
            {
                String extension = fileName.substring(lastDotIndex);
                // 验证是否为图片扩展名
                String[] validExtensions = {".jpg", ".jpeg", ".png", ".gif", ".bmp"};
                for (String validExt : validExtensions)
                {
                    if (extension.toLowerCase().equals(validExt))
                    {
                        return extension;
                    }
                }
            }
            
            // 默认返回.jpg
            return ".jpg";
        }
        catch (Exception e)
        {
            log.warn("获取文件扩展名失败，使用默认扩展名.jpg");
            return ".jpg";
        }
    }
    
    /**
     * 检测结果封装类
     */
    public static class DetectionResult
    {
        private boolean success;
        private String rawResponse;
        private BigDecimal confidence;
        private BigDecimal confThreshold;
        private Integer danger;
        
        public boolean isSuccess()
        {
            return success;
        }
        
        public void setSuccess(boolean success)
        {
            this.success = success;
        }
        
        public String getRawResponse()
        {
            return rawResponse;
        }
        
        public void setRawResponse(String rawResponse)
        {
            this.rawResponse = rawResponse;
        }
        
        public BigDecimal getConfidence()
        {
            return confidence;
        }
        
        public void setConfidence(BigDecimal confidence)
        {
            this.confidence = confidence;
        }
        
        public BigDecimal getConfThreshold()
        {
            return confThreshold;
        }
        
        public void setConfThreshold(BigDecimal confThreshold)
        {
            this.confThreshold = confThreshold;
        }
        
        public Integer getDanger()
        {
            return danger;
        }
        
        public void setDanger(Integer danger)
        {
            this.danger = danger;
        }
    }
}